/*************************************************************************
 *  Copyright © 2023-2030 FXB CO.,LTD. All rights reserved.
 *------------------------------------------------------------------------
 *  公司：DefaultCompany
 *  项目：CustomBuildProcess
 *  文件：LogItemOperateWindow.cs
 *  作者：Administrator
 *  日期：2025/6/10 21:59:11
 *  功能：Nothing
*************************************************************************/

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace CustomBuildProcess.Editor
{
    public class LogItemOperateWindow : EditorWindow
    {
        public ReorderableList list;

        public BuildConfigItem logConfigItem;
        public string propertyName;
        public SerializedObject logConfigSerializedObject;
        public SerializedProperty logItemProperty;
        private List<LogItemKeyValuePair> logItemList;

        public Rect parentRect;

        private Vector2 scrollView;

        private string key;
        private string value;
        private Action<string, string> addCallBack;
        private bool isValidating = true;
        private string errorMessage = string.Empty;

        private static float defaultScrollHeight = 360; // 滚动视图的高度
        private static float scrollHeight = 360; // 滚动视图的高度
        private static float logItemHeight;
        private static float windowHeight;

        // 显示自定义窗口的方法
        public static void ShowWindow(EditorWindow parentWindow, string propertyName)
        {
            LogItemOperateWindow instance = GetWindow<LogItemOperateWindow>("Log Item Operate Window");
            instance.propertyName = propertyName;
            instance.parentRect = parentWindow.position;
            instance.InitializedList();
            instance.Show();
        }

        private void CalculateWindowHeight()
        {
            logItemHeight = list.GetHeight(); // 根据列表项数量动态调整高度
            if (logItemHeight >= defaultScrollHeight)
                windowHeight = defaultScrollHeight;
            else
                windowHeight = logItemHeight;
        }

        private void ResizeWindowHeight(float height)
        {
            Rect newPos = position;
            newPos.height = height;
            newPos.x = parentRect.x + (parentRect.width - position.width) / 2;
            newPos.y = parentRect.y + (parentRect.height - height) / 2;
            position = newPos;

            // 可选：设置最小最大尺寸限制
            minSize = maxSize = new Vector2(position.width, height);
        }

        private void OnEnable()
        {
            InitializedList();
        }

        private void InitData()
        {
            logConfigItem = Resources.Load<BuildConfigItem>(PathManager.BuildConfigItemPath);

            logConfigSerializedObject = new SerializedObject(logConfigItem);
            logItemProperty = logConfigSerializedObject.FindProperty(propertyName);
            logItemList = GetLogItemList(logItemProperty);
        }

        private void InitializedList()
        {
            if (string.IsNullOrEmpty(propertyName)) return;

            InitData();

            // 初始化 ReorderableList
            list = new ReorderableList(logConfigSerializedObject, logItemProperty, true, true, true, true)
            {
                // 设置每一项的高度
                elementHeightCallback = (index) =>
                {
                    return EditorGUIUtility.singleLineHeight * 2;
                },
                drawElementBackgroundCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
                {
                    // 只在非激活、非聚焦状态下绘制自定义颜色
                    if (!isActive && !isFocused)
                    {
                        Color color = index % 2 == 0 ? new Color(0.2f, 0.2f, 0.2f) : new Color(0.3f, 0.3f, 0.3f);

                        EditorGUI.DrawRect(rect, color);
                    }

                    ReorderableList.defaultBehaviours.DrawElementBackground(rect, index, isActive, isFocused, true);
                },
                // 绘制列表项
                drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
                {
                    float indentLevel = -20; // 可以根据需要调整缩进级别
                    float singleHeight = EditorGUIUtility.singleLineHeight;

                    EditorGUILayout.BeginHorizontal();

                    //// 计算拖动手柄位置（垂直居中）
                    float handleSize = singleHeight;
                    float handleY = rect.y + (rect.height - handleSize) * 0.5f;
                    Rect handleRect = new Rect(rect.x + indentLevel, handleY, handleSize, handleSize);
                    Rect handleRect1 = new Rect(rect.x + indentLevel, handleY + handleSize / 2, handleSize, handleSize);
                    ReorderableList.defaultBehaviours.DrawElementDraggingHandle(handleRect, index, isActive, isFocused, true);
                    ReorderableList.defaultBehaviours.DrawElementDraggingHandle(handleRect1, index, isActive, isFocused, true);

                    // 显示索引
                    float indexY = rect.y + (rect.height - singleHeight) / 2;
                    Rect indexRect = new Rect(handleRect.xMax, indexY, 40, singleHeight);
                    EditorGUI.LabelField(indexRect, index.ToString());

                    EditorGUILayout.BeginVertical();

                    float width = (rect.width - indexRect.width) * 0.475f;
                    float during = (rect.width - indexRect.width) * 0.05f;

                    //绘制key value  Label
                    EditorGUILayout.BeginHorizontal();
                    float keyValueY = rect.y + (rect.height / 2 - singleHeight) / 2;
                    Rect keyRect = new Rect(indexRect.xMax, keyValueY, width, singleHeight);
                    EditorGUI.LabelField(keyRect, "Key");
                    Rect valueRect = new Rect(keyRect.xMax + during, keyValueY, width, singleHeight);
                    EditorGUI.LabelField(valueRect, "Value");
                    EditorGUILayout.EndHorizontal();

                    //绘制字符串字段和显示名称字段
                    EditorGUILayout.BeginHorizontal();
                    {
                        float keyValueTextY = keyRect.yMax + (rect.height / 2 - singleHeight) / 2;
                        Rect textFieldRect = new Rect(indexRect.xMax, keyValueTextY, width, singleHeight);
                        Rect valueTextFieldRect = new Rect(textFieldRect.xMax + during, keyValueTextY, width, singleHeight);

                        // 绘制字符串字段
                        var element = logItemProperty.GetArrayElementAtIndex(index);
                        var keyElement = element.FindPropertyRelative("key");
                        var valueElement = element.FindPropertyRelative("value");

                        EditorGUI.PropertyField(textFieldRect, keyElement, GUIContent.none);
                        EditorGUI.PropertyField(valueTextFieldRect, valueElement, GUIContent.none);
                    }
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.EndVertical();
                    EditorGUILayout.EndHorizontal();
                },

                onAddCallback = (ReorderableList l) =>
                {
                    ResizeWindowHeight(position.height + 80);
                    addCallBack = (key, value) =>
                    {
                        ReorderableList.defaultBehaviours.DoAddButton(l);
                        var element = logItemProperty.GetArrayElementAtIndex(l.index);
                        var keyElement = element.FindPropertyRelative("key");
                        var valueElement = element.FindPropertyRelative("value");
                        keyElement.stringValue = key;
                        valueElement.stringValue = value;

                        logItemList = GetLogItemList(logItemProperty);

                        CalculateWindowHeight();
                        ResizeWindowHeight(windowHeight);

                        scrollView.y = logItemHeight - scrollHeight;

                        // 提交更改
                        logConfigSerializedObject.ApplyModifiedProperties();

                        // 标记对象为 dirty（需要在 Editor 下才能调用）
                        EditorUtility.SetDirty(logConfigItem);

                        // 保存修改到磁盘
                        AssetDatabase.SaveAssets();
                    };
                },
                drawHeaderCallback = rect =>
                {
                    char[] letters = propertyName.ToCharArray();
                    letters[0] = char.ToUpper(letters[0]);

                    EditorGUI.LabelField(rect, new string(letters), EditorStyles.boldLabel);
                },

                // 当移除元素时触发
                onRemoveCallback = (ReorderableList l) =>
                {
                    if (EditorUtility.DisplayDialog("确认删除", "确定要删除此元素吗？", "删除", "取消"))
                    {
                        ReorderableList.defaultBehaviours.DoRemoveButton(l);

                        logItemList = GetLogItemList(logItemProperty);

                        CalculateWindowHeight();
                        ResizeWindowHeight(windowHeight);

                        // 应用修改
                        logConfigSerializedObject.ApplyModifiedProperties();

                        // 标记对象为 dirty，以便保存更改到磁盘（如果需要）
                        EditorUtility.SetDirty(logConfigItem);

                        // 保存 Asset 到磁盘（如果是 ScriptableObject）
                        AssetDatabase.SaveAssets();
                    }
                }
            };

            CalculateWindowHeight();
            ResizeWindowHeight(windowHeight);
        }

        List<LogItemKeyValuePair> GetLogItemList(SerializedProperty listProperty)
        {
            List<LogItemKeyValuePair> list = new List<LogItemKeyValuePair>();
            for (int i = 0; i < listProperty.arraySize; i++)
            {
                SerializedProperty element = listProperty.GetArrayElementAtIndex(i);
                string key = element.FindPropertyRelative("key").stringValue;
                string value = element.FindPropertyRelative("value").stringValue;
                list.Add(new LogItemKeyValuePair(key, value));
            }
            return list;
        }


        private void OnGUI()
        {
            logConfigSerializedObject.Update(); // 手动更新

            if (logItemHeight < defaultScrollHeight)
                scrollHeight = logItemHeight;
            else
                scrollHeight = defaultScrollHeight;

            scrollView = EditorGUILayout.BeginScrollView(scrollView, GUILayout.Height(scrollHeight));

            list.DoLayoutList();
            EditorGUILayout.EndScrollView();

            EditorGUILayout.Space(10);

            if (addCallBack != null)
            {
                if (!isValidating)
                    EditorGUILayout.HelpBox(errorMessage, MessageType.Warning);

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.LabelField("Key", EditorStyles.boldLabel, GUILayout.Width(55));
                    key = EditorGUILayout.TextField(key);
                    if (EditorGUI.EndChangeCheck())
                    {
                        if (!isValidating)
                        {
                            isValidating = true;
                            ResizeWindowHeight(windowHeight + 80);
                        }
                    }
                }

                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.LabelField("Value", EditorStyles.boldLabel, GUILayout.Width(55));
                    value = EditorGUILayout.TextField(value);
                    if (EditorGUI.EndChangeCheck())
                    {
                        if (!isValidating)
                        {
                            isValidating = true;
                            ResizeWindowHeight(windowHeight + 80);
                        }
                    }
                }
                EditorGUILayout.EndHorizontal();


                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button("Add", GUILayout.Height(25)))
                    {
                        if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value))
                        {
                            errorMessage = "Key or Value cannot be empty.";
                            isValidating = false;
                            ResizeWindowHeight(windowHeight + 120);
                        }
                        else if (logItemList.Contains(new LogItemKeyValuePair(key, value)))
                        {
                            errorMessage = "Key or Value already exist.";
                            isValidating = false;
                            ResizeWindowHeight(windowHeight + 120);
                        }
                        else
                        {
                            addCallBack?.Invoke(key, value);
                            addCallBack = null;
                            isValidating = true;
                            key = string.Empty;
                            value = string.Empty;
                            GUI.FocusControl(null); // 取消焦点
                            ResizeWindowHeight(windowHeight);
                        }
                    }

                    if (GUILayout.Button("Cancle", GUILayout.Height(25)))
                    {
                        addCallBack = null;
                        key = string.Empty;
                        value = string.Empty;
                        isValidating = true;
                        GUI.FocusControl(null); // 取消焦点
                        ResizeWindowHeight(windowHeight);
                    }
                }
                EditorGUILayout.EndHorizontal();
            }

            logConfigSerializedObject.ApplyModifiedProperties(); // 应用修改
        }
    }
}


